//
//  NetTokk.swift
//  dysaidao
//
//  Created by Penlon Kim on 2021/11/11.
//  Copyright © 2021 王锦发. All rights reserved.
//

import Foundation
import Reachability

// 定义网络状态枚举
@objc public enum NetStatus: Int {
    case unknown
    case notReachable
    case cellular
    case wifi
}

// 网络状态监控工具类
@objcMembers
class NetTokk: NSObject {
    
    @objc public static let shared = NetTokk()
    
    typealias NetChange = (NetStatus) -> Void
    /// 网络状态变化时触发的闭包
    private var onStatusChange: NetChange?
    
    /// 监听网络状态变化
    @objc public func onChange(by callback: @escaping NetChange, nonono: Bool = false) {
        onStatusChange = callback
        if nonono {
            self.notifyCurrentStatus()
        }
    }
    
    // Reachability实例
    private var reachability: Reachability?

    override init() {
        super.init()
        setupReachability()
    }

    // 设置Reachability监听
    private func setupReachability() {
        reachability = try? Reachability()
        
        // 网络可达时的处理
        reachability?.whenReachable = { [weak self] reachability in
            guard let weakSelf = self else { return }
            let status: NetStatus = reachability.connection == .wifi ? .wifi : .cellular
            weakSelf.onStatusChange?(status) // 通知网络状态改变
            print("网络状态改变为 >>> \(status.rawValue)")
        }
        
        // 网络不可达时的处理
        reachability?.whenUnreachable = { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.onStatusChange?(.notReachable) // 通知网络状态改变
            print("网络状态改变为 >>> \(NetStatus.notReachable.rawValue)")
        }
    }

    /// 开始监听网络状态
    @objc public func startMonitoring() {
        do {
            try reachability?.startNotifier()
            print("开始监听网络状态")
        } catch {
            print("无法启动网络状态监听")
        }
    }

    /// 停止监听网络状态
    @objc public func stopMonitoring() {
        reachability?.stopNotifier()
        print("停止监听网络状态")
    }

    /// 检查网络是否可用
    /// - Returns: 网络是否可用
    @objc public func checkNet() -> Bool {
        return reachability?.connection != .unavailable
    }
    
    /// 主动通知当前网络状态
    private func notifyCurrentStatus() {
        guard let reachability = reachability else {
            onStatusChange?(.unknown)
            return
        }
        
        let status: NetStatus
        switch reachability.connection {
        case .wifi:
            status = .wifi
        case .cellular:
            status = .cellular
        case .unavailable:
            status = .notReachable
        }
        
        onStatusChange?(status)
        print("当前网络状态 >>> \(status)")
    }
    
}
